﻿<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
	Home Page
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
	<h1>MvcCss</h1>
	<p>
	MvcCss is an attempt to bring the convention-based simplicity of MVC to CSS.
	</p>

	<h2>What it's for</h2>
	<p>
	In a project of any size, CSS tends to get a bit out of control.
	</p>
	<p>
	Certainly, you've worked on a project where there is a large CSS file of hundreds of selectors. You make a change intended for one page, and you discover that it's
	broken the layout somewhere else.
	</p>
	
	<h2>What it does</h2>
	<p>
	MvcCss offers two benefits: a simple convention for <strong>managing scope</strong>, and <strong>automatic references</strong> to appropriate CSS files.
	</p>
	<h3>The BODY tag</h3>
	<p>
	First, MvcCss renders a simple body tag with <strong>attributes</strong> based on controller and action. For example:
	</p>

	<pre><%= Html.Encode("<body class=\"about\" id=\"about-staff\">") %></pre>

	<p>This allows you to scope your selectors in CSS, like:</p>

	<pre><%= Html.Encode(".about { line-height:1.2em } ") %>                   /* applies to all About pages */</pre>
	<pre><%= Html.Encode("#about-staff img.person { float:right } ") %>        /* applies only to About/Staff, aka the About.Staff() action */ </pre>

	<p>...with confidence that it will only apply on the specified pages.</p>

	<h3>The CSS files</h3>
	<p>
	MvcCss <strong>handles CSS files the way MVC handles views</strong>: if you name your files conventionally, they will automatically be
	rendered.
	</p>

	<p>
	If you create a CSS file in the "Content" folder, with the name "About.css", the CSS <%= Html.Encode("<link>")%> tag will automatically be included in all pages on your About controller.
	</p>
	<p>
	You can even create a CSS file called "About-Contact.css", and that file automatically will be included <em>only</em> for your Search.Contact() action.
	[This probably is not best-practice, though, see below.]
	</p>

	<h2>How to implement</h2>

	<p>First, reference in MvcCss.dll from your MVC project. You'll find it in the /bin directory of this Demo Web site.</p>

	<p>Second, replace the opening and closing <%= Html.Encode("<body>")%> tags in your master page with</p>

	<pre>&lt;% using (Html.BeginBody()) { %&gt;</pre>

	<pre>&lt;-- The existing ContentPlaceHolders and such --&gt;</pre>

	<pre>&lt;% } %&gt;</pre>
	
	<p>Finally, in the <%= Html.Encode("<head>")%> of your master page, after your main CSS, include:</p>

	<pre>&lt;%= Html.MvcCss() %&gt;</pre>

	<p>That's it! Now go about writing your CSS as described above, and MvcCss will take it from there.</p>
	<h2>A word about CSS optimization</h2>
	<p>
	People have different ideas about the optimal way to organize CSS.
	</p>
	<p>
	There is a conventional wisdom that all of your CSS should be in one big file, to minimize HTTP requests.
	What often goes unmentioned is the cost: unused CSS selectors all over your site.
	</p>
	<p>
	<img src="/Content/cssaudit.png" alt="288 unused selectors" />
	</p>

	<p>...which means that the browser is querying the DOM a lot more than it needs to.</p>
	<p>
	As a practical matter, I have settled on adding (up to) <strong>one specific CSS file per controller</strong>, in addition to the site-wide CSS.
	An About.css file, for everything under /About, would fit this bill.
	</p>
	<p>
	This, to me, balances all sides of the optimization equation: HTTP requests vs unused selectors vs manageability.
	</p>

</asp:Content>
